#if defined(WIN32) && !defined(CRTL)

#define HEAP_NO_SERIALIZE (1)
extern void * API HeapCreate(uint32_t Options, size_t InitialSize, size_t MaximumSize);
extern unsigned API HeapDestroy(void *Heap);
extern void * API HeapAlloc(void *Heap, uint32_t Flags, size_t Bytes);
extern void * API HeapReAlloc(void *Heap, uint32_t Flags, void *Mem, size_t Bytes);
extern unsigned API HeapFree(void *Heap, uint32_t Flags, void const *Mem);

#else

void * API malloc(size_t size);
void * API realloc(void *mem, size_t size);
void API free(void *mem);

#endif

#if defined(WIN32) && !defined(CRTL)

typedef void *heap_t;

#else

typedef struct heap_header_t {
	struct heap_header_t *previous;
	struct heap_header_t *next;
} heap_header_t;

typedef heap_header_t *heap_t;

#endif

static inline heap_t memory_create_heap(void)
{
#if defined(WIN32) && !defined(CRTL)
	return HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
#else
	heap_t result = malloc(sizeof(heap_header_t));
	if(result != 0){
		result->previous = result;
		result->next = result;
	}
	return result;
#endif
}

static inline void memory_destroy_heap(heap_t heap)
{
#if defined(WIN32) && !defined(CRTL)
	HeapDestroy(heap);
#else
	heap_header_t *i = heap->previous;
	while(i != heap){
		heap_header_t *n = i->previous;
		free(i);
		i = n;
	}
	free(heap);
#endif
}

static inline void *memory_allocate(heap_t heap, unsigned size)
{
#if defined(WIN32) && !defined(CRTL)
	return HeapAlloc(heap, 0, size);
#else
	heap_header_t *result = malloc(sizeof(heap_header_t) + size);
	if(result != 0){
		heap_header_t *previous = heap->previous;
		result->previous = previous;
		result->next = heap;
		previous->next = result;
		heap->previous = result;
		++ result;
	}
	return result;
#endif
}

#ifdef __DYAZMEMORY__REALLOCATE__
static inline void *memory_reallocate(heap_t heap, void *memory, unsigned size)
{
#if defined(WIN32) && !defined(CRTL)
	return HeapReAlloc(heap, 0, memory, size);
#else
	heap_header_t *previous;
	heap_header_t *next;
	heap_header_t *new_block;
	heap_header_t *block;
	if(memory == 0){
		return memory_allocate(heap, size);
	}
	block = memory;
	-- block;
	previous = block->previous;
	next = block->next;
	new_block = realloc(block, sizeof(heap_header_t) + size);
	if(new_block == 0){
		if(size != 0) free(block);
		previous->next = next;
		next->previous = previous;
		return 0;
	}else{
		if(new_block != block){
			previous->next = new_block;
			next->previous = new_block;
		}
		++ new_block;
		return new_block;
	}
#endif
}
#endif

static inline void memory_free(heap_t heap, void const *memory)
{
#if defined(WIN32) && !defined(CRTL)
	HeapFree(heap, 0, memory);
#else
	heap_header_t *previous;
	heap_header_t *next;
	heap_header_t *block = (heap_header_t *)memory;
	-- block;
	previous = block->previous;
	next = block->next;
	previous->next = next;
	next->previous = previous;
	free(block);
#endif
}
